home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / caplib / part01 next >
Encoding:
Text File  |  1990-12-17  |  12.0 KB  |  545 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: mjr@decuac.DEC.COM
  3. subject: v15i104: capabilities database routines (lifted from BSD printcap code)
  4. from: mjr@decuac.DEC.COM (Marcus J. Ranum)
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 104
  8. Submitted-by: mjr@decuac.DEC.COM (Marcus J. Ranum)
  9. Archive-name: caplib/part01
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of shell archive."
  18. # Contents:  caplib.3 caplib.c
  19. # Wrapped by mjr@hussar.dco.dec.com on Wed Nov 28 22:14:23 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f caplib.3 -a "${1}" != "-c" ; then 
  22.   echo shar: Will not over-write existing file \"caplib.3\"
  23. else
  24. echo shar: Extracting \"caplib.3\" \(4168 characters\)
  25. sed "s/^X//" >caplib.3 <<'END_OF_caplib.3'
  26. X.\" Copyright (c) 1980 The Regents of the University of California.
  27. X.\" All rights reserved.
  28. X.\"
  29. X.\" Redistribution and use in source and binary forms are permitted provided
  30. X.\" that: (1) source distributions retain this entire copyright notice and
  31. X.\" comment, and (2) distributions including binaries display the following
  32. X.\" acknowledgement:  ``This product includes software developed by the
  33. X.\" University of California, Berkeley and its contributors'' in the
  34. X.\" documentation or other materials provided with the distribution and in
  35. X.\" all advertising materials mentioning features or use of this software.
  36. X.\" Neither the name of the University nor the names of its contributors may
  37. X.\" be used to endorse or promote products derived from this software without
  38. X.\" specific prior written permission.
  39. X.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  40. X.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  41. X.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  42. X.\"
  43. X.\"    @(#)termcap.3    6.5 (Berkeley) 6/23/90
  44. X.\"
  45. X.\" modified to reflect caplib changes by Marcus Ranum, DEC, 1990
  46. X.\"    mjr@decuac.dec.com
  47. X.\"
  48. X.TH CAPLIB 3 "Dec 1, 1990"
  49. X.UC 4
  50. X.SH NAME
  51. Xcapgetent, capgetnum, capgetflag, capgetstr \- capabilities database routines.
  52. X.SH SYNOPSIS
  53. X.nf
  54. X.PP
  55. X.B capgetent(capfile, name, capbuf, capbufsiz)
  56. X.B char *capfile, *name, *capbuf;
  57. X.B int capbufsiz;
  58. X.PP
  59. X.B capgetnum(capbuf, id)
  60. X.B char *capbuf, *id;
  61. X.PP
  62. X.B capgetflag(capbuf,id)
  63. X.B char *capbuf, *id;
  64. X.PP
  65. X.B char *
  66. X.B capgetstr(capbuf, id, area, asizep)
  67. X.B char *capbuf, *id, **area;
  68. X.B int *asizep;
  69. X.PP
  70. X.B capgetnext(fp, capbuf, capbufsiz)
  71. X.B FILE *fp;
  72. X.B char *capbuf;
  73. X.B int capbufsiz;
  74. X.fi
  75. X.SH DESCRIPTION
  76. XThese functions extract and use capabilities from a terminal capability-style
  77. Xdata base, the format of which is described in
  78. X.IR termcap (5).
  79. X.PP
  80. X.I Capgetent
  81. Xextracts the entry for the capability from the file named
  82. X.I capfile
  83. Xand the entry
  84. X.I name
  85. Xinto the buffer at
  86. X.I capbuf.
  87. X.I Capbuf
  88. Xis assumed to be at least of size capbufsiz
  89. Xand may be passed to subsequent calls to
  90. X.I capgetnum,
  91. X.I capgetflag,
  92. Xand
  93. X.I capgetstr.
  94. X.I Capgetent
  95. Xreturns \-1 if the
  96. Xdata base file could be opened,
  97. X0 if the capability name given does not have an entry,
  98. X2 if the buffer is not sufficiently large,
  99. Xand 1 if all goes well.
  100. X.I Capgetent
  101. Xdoes not check for environment variables or user-defined capabilities
  102. Xfiles, though such searches can easily be performed as a higher level
  103. Xof software that makes multiple calls to 
  104. X.I capgetent.
  105. X.PP
  106. X.I Capgetnum
  107. Xgets the numeric value of capability
  108. X.I id,
  109. Xfrom the capability buffer
  110. X.I capbuf
  111. Xreturning \-1 if is not given for the database entry.
  112. X.I Capgetflag
  113. Xreturns 1 if the specified capability is present in
  114. Xthe database's entry, 0 if it is not.
  115. X.I Capgetstr
  116. Xreturns the string value of the capability
  117. X.I id,
  118. Xfrom the buffer
  119. X.I capbuf,
  120. Xplaces it in a second buffer at
  121. X.I area,
  122. Xand advances the
  123. X.I area
  124. Xpointer. The remaining amount of space in
  125. X.I area
  126. Xis stored in
  127. X.I asizep
  128. Xand is adjusted as more space is used. If
  129. X.I asizep
  130. Xis a null pointer, the size of the buffer is assumed to be infinite. You
  131. Xare warned. When a call to
  132. X.I capgetstr
  133. Xis made initially, the value of the contents of
  134. X.I asizep
  135. Xshould accurately reflect the size of the area.
  136. XIt decodes the abbreviations for this field described in
  137. X.IR termcap (5).
  138. X.I Capgetstr
  139. Xreturns NULL if the capability was not found.
  140. X.PP
  141. X.I Capgetnext
  142. Xreads the next database entry from the FILE pointer
  143. X.I fp
  144. Xinto the space provided at
  145. X.I capbuf
  146. Xup to a maximum size of
  147. X.I capbufsiz. 
  148. X1 is returned if the read was succesful, 0 is returned at end-of-file,
  149. X-1 is returned if the FILE pointer is a null pointer, and 2 is returned
  150. Xif the space provided was insufficient.
  151. X.SH FILES
  152. X.SH LIMITATIONS
  153. XThe caplib library differs from
  154. X.I termcap
  155. Xin that the "tc=" kludge has been removed and size checking has been
  156. Xadded. Checking environmental variables is not supported as in
  157. X.I termcap
  158. Xbut can easily be supported in higher-level code (which is where
  159. Xit belonged in the first place). No file descriptors are kept open,
  160. Xnor are there any globals.
  161. X.DT
  162. X.SH SEE ALSO
  163. Xex(1), curses(3), termcap(5)
  164. END_OF_caplib.3
  165. if test 4168 -ne `wc -c <caplib.3`; then
  166.     echo shar: \"caplib.3\" unpacked with wrong size!
  167. fi
  168. # end of overwriting check
  169. fi
  170. if test -f caplib.c -a "${1}" != "-c" ; then 
  171.   echo shar: Will not over-write existing file \"caplib.c\"
  172. else
  173. echo shar: Extracting \"caplib.c\" \(6015 characters\)
  174. sed "s/^X//" >caplib.c <<'END_OF_caplib.c'
  175. X/*
  176. X * Copyright (c) 1983 Regents of the University of California.
  177. X * All rights reserved.
  178. X *
  179. X * Redistribution and use in source and binary forms are permitted
  180. X * provided that the above copyright notice and this paragraph are
  181. X * duplicated in all such forms and that any documentation,
  182. X * advertising materials, and other materials related to such
  183. X * distribution and use acknowledge that the software was developed
  184. X * by the University of California, Berkeley.  The name of the
  185. X * University may not be used to endorse or promote products derived
  186. X * from this software without specific prior written permission.
  187. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  188. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  189. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  190. X */
  191. X
  192. X/*
  193. X * From the BSD lpd source, cleaned into a general library by
  194. X * Marcus J. Ranum, Digital Equipment Corporation. 1990
  195. X *
  196. X * I took out the code that handled the multiple tc= entries, as
  197. X * the manner in which it was implemented was so vile, and nauseating
  198. X * as to be unmentionable. :) I added buffer-boundary checking everywhere
  199. X * appropriate, so now you can use more than BUFSIZ worth of information
  200. X * if that turns you on.
  201. X */
  202. X
  203. X#include <ctype.h>
  204. X#include <stdio.h>
  205. X
  206. X
  207. X/*
  208. X * capnamatch deals with name matching.  The first field of the
  209. X * entry is a sequence of names separated by |'s, so we compare
  210. X * against each such name.  The normal : terminator after the last
  211. X * name (before the first field) stops us.
  212. X */
  213. Xstatic    int
  214. Xcapnamatch(tbuf,np)
  215. Xregister char    *tbuf;
  216. Xchar    *np;
  217. X{
  218. X    register char    *p1;
  219. X
  220. X    if (*tbuf == '#')
  221. X        return(0);
  222. X    for (;;) {
  223. X        for (p1 = np; *p1 && *tbuf == *p1; tbuf++, p1++)
  224. X            continue;
  225. X
  226. X        if (*p1 == 0 && (*tbuf == '|' || *tbuf == ':' || *tbuf == 0))
  227. X            return(1);
  228. X
  229. X        while (*tbuf && *tbuf != ':' && *tbuf != '|')
  230. X            tbuf++;
  231. X
  232. X        if (*tbuf == 0 || *tbuf == ':')
  233. X            return(0);
  234. X        tbuf++;
  235. X    }
  236. X}
  237. X
  238. X
  239. X
  240. X
  241. Xcapgetnext(fp,bp,bsiz)
  242. XFILE        *fp;
  243. Xregister char    *bp;
  244. Xint        bsiz;
  245. X{
  246. X    register int    c;
  247. X    register int    skip = 0;
  248. X    char        *tbuf;
  249. X
  250. X    if (fp == NULL)
  251. X        return(-1);
  252. X
  253. X    tbuf = bp;
  254. X    for (;;) {
  255. X        switch (c = getc(fp)) {
  256. X        case EOF:
  257. X            fp = NULL;
  258. X            return(0);
  259. X
  260. X        case '\n':
  261. X            if(bp == tbuf) {
  262. X                skip = 0;
  263. X                continue;
  264. X            }
  265. X            if (bp[-1] == '\\') {
  266. X                bp--;
  267. X                continue;
  268. X            }
  269. X            *bp = '\0';
  270. X            return(1);
  271. X
  272. X        case '#':
  273. X            if (bp == tbuf)
  274. X                skip++;
  275. X
  276. X        default:
  277. X            if (skip)
  278. X                continue;
  279. X            if (bp >= tbuf + bsiz) {
  280. X                *bp = '\0';
  281. X                return(2);
  282. X            }
  283. X            *bp++ = c;
  284. X        }
  285. X    }
  286. X}
  287. X
  288. X
  289. X
  290. X
  291. Xstatic char *
  292. Xcapskip(bp)
  293. Xregister char    *bp;
  294. X{
  295. X
  296. X    while((*bp != '\0' && *bp != ':') || (*(bp - 1) == '\\' && *bp == ':'))
  297. X        bp++;
  298. X
  299. X    if(*bp == ':')
  300. X        bp++;
  301. X
  302. X    return(bp);
  303. X}
  304. X
  305. X
  306. X
  307. X
  308. X
  309. X/*
  310. X * Get an entry for entr "name" in buffer bp,
  311. X * from the cap file.  Parse is very rudimentary;
  312. X * we just notice escaped newlines.
  313. X */
  314. Xcapgetent(capfile,name,bp,bsiz)
  315. Xchar        *capfile;
  316. Xchar        *name;
  317. Xchar        *bp;
  318. Xint        bsiz;
  319. X{
  320. X    register char    *cp;
  321. X    register int    c;
  322. X    register int    i = 0;
  323. X    register int    cnt = 0;
  324. X    char        *tbuf;
  325. X    FILE         *tf = (FILE *)NULL;
  326. X    char        *cp2;
  327. X
  328. X    tbuf = bp;
  329. X    
  330. X    if((tf = fopen(capfile,"r")) == (FILE *)NULL)
  331. X        return(-1);
  332. X
  333. X    for(;;) {
  334. X        cp = bp;
  335. X
  336. X        for(;;) {
  337. X            if((c = getc(tf)) == EOF) {
  338. X                (void)fclose(tf);
  339. X                return(0);
  340. X            }
  341. X
  342. X            if (c == '\n') {
  343. X                if(cp > bp && *(cp - 1) == '\\'){
  344. X                    cp--;
  345. X                    continue;
  346. X                }
  347. X                break;
  348. X            }
  349. X
  350. X            if (cp >= bp + bsiz)
  351. X                return(2);
  352. X
  353. X            *cp++ = c;
  354. X        }
  355. X        *cp = 0;
  356. X
  357. X        /* The real work for the match. */
  358. X        if(capnamatch(tbuf,name)) {
  359. X            (void)fclose(tf);
  360. X            return(1);
  361. X        }
  362. X    }
  363. X}
  364. X
  365. X
  366. X
  367. X
  368. X
  369. X/*
  370. X * Return the (numeric) option id.
  371. X * Numeric options look like
  372. X *    li#80
  373. X * i.e. the option string is separated from the numeric value by
  374. X * a # character.  If the option is not found we return -1.
  375. X * Note that we handle octal numbers beginning with 0.
  376. X */
  377. Xcapgetnum(tbuf,id)
  378. Xchar        *tbuf;
  379. Xchar        *id;
  380. X{
  381. X    register int i, base;
  382. X    register char *bp = tbuf;
  383. X
  384. X    for (;;) {
  385. X        bp = capskip(bp);
  386. X        if(*bp == 0)
  387. X            return(-1);
  388. X
  389. X        if(*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
  390. X            bp++;
  391. X            if(*bp == '@')
  392. X                return(-1);
  393. X
  394. X            if(*bp != '#')
  395. X                continue;
  396. X            bp++;
  397. X            base = 10;
  398. X            if (*bp == '0')
  399. X                base = 8;
  400. X            i = 0;
  401. X
  402. X            while (isdigit(*bp))
  403. X                i *= base, i += *bp++ - '0';
  404. X
  405. X            return(i);
  406. X        }
  407. X    }
  408. X}
  409. X
  410. X
  411. X
  412. X
  413. X/*
  414. X * Handle a flag option.
  415. X * Flag options are given "naked", i.e. followed by a : or the end
  416. X * of the buffer.  Return 1 if we find the option, or 0 if it is
  417. X * not given.
  418. X */
  419. Xcapgetflag(tbuf,id)
  420. Xchar        *tbuf;
  421. Xchar        *id;
  422. X{
  423. X    register char *bp = tbuf;
  424. X
  425. X    for(;;) {
  426. X        bp = capskip(bp);
  427. X        if(!*bp)
  428. X            return (0);
  429. X
  430. X        if(*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
  431. X            if(!*bp || *bp == ':')
  432. X                return(1);
  433. X            else
  434. X                if(*bp == '@')
  435. X                    return(0);
  436. X        }
  437. X    }
  438. X}
  439. X
  440. X
  441. X
  442. X
  443. X/*
  444. X * capdecode does the grung work to decode the
  445. X * string capability escapes.
  446. X */
  447. Xstatic char *
  448. Xcapdecode(str,area,asiz)
  449. Xregister char    *str;
  450. Xchar        **area;
  451. Xint        *asiz;
  452. X{
  453. X    register char    *cp;
  454. X    register int    c;
  455. X    register char    *dp;
  456. X    int        i;
  457. X
  458. X    cp = *area;
  459. X
  460. X    while((c = *str++) && c != ':') {
  461. X        switch (c) {
  462. X
  463. X        case '^':
  464. X            c = *str++ & 037;
  465. X            break;
  466. X
  467. X        case '\\':
  468. X            dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
  469. X            c = *str++;
  470. Xnextc:
  471. X            if (*dp++ == c) {
  472. X                c = *dp++;
  473. X                break;
  474. X            }
  475. X            dp++;
  476. X            if (*dp)
  477. X                goto nextc;
  478. X
  479. X            if(isdigit(c)) {
  480. X                c -= '0', i = 2;
  481. X                do {
  482. X                    c <<= 3, c |= *str++ - '0';
  483. X                } while(--i && isdigit(*str));
  484. X            }
  485. X            break;
  486. X        }
  487. X
  488. X        if(asiz != (int *)0 && (*asiz)-- <= 0)
  489. X            return(NULL);
  490. X
  491. X        *cp++ = c;
  492. X    }
  493. X    *cp++ = 0;
  494. X    str = *area;
  495. X    *area = cp;
  496. X    return(str);
  497. X}
  498. X
  499. X
  500. X
  501. X
  502. X/*
  503. X * Get a string valued option.
  504. X * These are given as
  505. X *    cl=^Z
  506. X * Much decoding is done on the strings, and the strings are
  507. X * placed in area, which is a ref parameter which is updated.
  508. X */
  509. Xchar *
  510. Xcapgetstr(tbuf,id,area,asiz)
  511. Xchar        *tbuf;
  512. Xchar        *id;
  513. Xchar        **area;
  514. Xint        *asiz;
  515. X{
  516. X    register char *bp = tbuf;
  517. X
  518. X    for (;;) {
  519. X        bp = capskip(bp);
  520. X        if (!*bp)
  521. X            return (0);
  522. X
  523. X        if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
  524. X            continue;
  525. X
  526. X        if (*bp == '@')
  527. X            return(0);
  528. X
  529. X        if (*bp != '=')
  530. X            continue;
  531. X        bp++;
  532. X        return(capdecode(bp,area,asiz));
  533. X    }
  534. X}
  535. END_OF_caplib.c
  536. if test 6015 -ne `wc -c <caplib.c`; then
  537.     echo shar: \"caplib.c\" unpacked with wrong size!
  538. fi
  539. chmod +x caplib.c
  540. # end of overwriting check
  541. fi
  542. echo shar: End of shell archive.
  543. exit 0
  544.  
  545.